package Arbitre;

import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
 
import org.w3c.dom.*;

import java.util.*;
import java.io.*;

public class Sauvegarde
{
    /**
     * Retour une chaine contenant le xml
     * Prend un iterateur sur une liste de configuration
     **/
    public String getXml(ListIterator<Configuration> list)
    {
        if (!list.hasNext())
            return null;

        Configuration c = list.next();

        try 
        {
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
	    
            // Element racine
            Document doc = docBuilder.newDocument();
            Element rootElement = doc.createElement("sauvegarde");
            doc.appendChild(rootElement);
	    
            // Largeur du terrain
            Element largeur = doc.createElement("largeur");
            largeur.appendChild(doc.createTextNode(String.valueOf(c.getLargeur())));
            rootElement.appendChild(largeur);
 
            // Hauteur du terrain
            Element hauteur = doc.createElement("hauteur");
            hauteur.appendChild(doc.createTextNode(String.valueOf(c.getHauteur())));
            rootElement.appendChild(hauteur);

            Element listeConfig = doc.createElement("configurations");
            // Le premier qu'on a choisi
            Element configuration = doc.createElement("data");
            configuration.appendChild(doc.createTextNode(c.getSerialize()));
            listeConfig.appendChild(configuration);	    


            while (list.hasNext())
            {
                c = list.next();
                configuration = doc.createElement("data");
                configuration.appendChild(doc.createTextNode(c.getSerialize()));
                listeConfig.appendChild(configuration);	    
            }
	    
            // Ajoute la configuration
            rootElement.appendChild(listeConfig);

            // Récupère la chaine et la renvoit
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);
 
            // Récupère dans la writer
            StringWriter writer = new StringWriter();
            StreamResult result = new StreamResult(writer);
 
            transformer.transform(source, result);
 
            return writer.getBuffer().toString();

        } 
        catch (ParserConfigurationException pce) 
        {
            return null;
        }
        catch (TransformerException tfe) 
        {
            return null;
        }
    }
    
    /**
     * Lis une chaine et retourne un iterateur 
     * Sur une liste de configuration
     **/
    public ListIterator<Configuration> readXml(String xml)
    {
        Pile<Configuration> pile = new Pile<Configuration>();

        try
        {
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
	    
            doc.getDocumentElement().normalize();
	    
            int hauteur = Integer.valueOf(doc.getElementsByTagName("hauteur").item(0).getTextContent());
            int largeur = Integer.valueOf(doc.getElementsByTagName("largeur").item(0).getTextContent());


            NodeList nList = doc.getElementsByTagName("data");
            for (int temp = 0; temp < nList.getLength(); temp++) 
            {
                Node nNode = nList.item(temp);
                Configuration c = new Configuration(largeur, hauteur, null);
                c.setSerialized(nNode.getTextContent());
                pile.push(c);
            }
	    
        }
        catch(Exception e)
        {
            System.err.println("Erreur lors de l'ouverture de la sauvegarde.");
            return null;
        }
	    
        return pile.iterator();
    }
}
